/*
 * lista.c
 *
 *  Created on: 19/07/2011
 *      Author: juan carlos
 */
#include <stdio.h>
#include <stdlib.h>
#include "lista.h"


/**
 * Inicializamos la lista enlazada
 */
Boolean inicializarLista(Lista_T *lista) {
	lista->tam = 0;
	lista->primero = NULL;
	lista->ultimo = NULL;

	printf("-> Lista Inicializada Correctamente \n");

	return TRUE;
}

/**
 * Libera la memoria ocupada por la lista
 */
Boolean liberarLista(Lista_T *lista) {
	Elemento_T *temp;
	Elemento_T *aux;

	temp = lista->primero;
	while (temp != NULL) {
		aux = temp->sig;
		free(temp);
		temp = aux;
		printf("-> Elemento Liberado Correctamente \n");
	}
	lista->primero = NULL;
	lista->ultimo = NULL;

	printf("-> Lista Liberada Correctamente \n");
	return TRUE;
}


/**
 * Inserta el primer elemento en la lista
 */
Boolean insertarPrimerElemento(Lista_T *lista, Estructura_T entrada) {
	Elemento_T *nuevo_elem;

	/* Reservamos memoria */
	nuevo_elem = (Elemento_T *) malloc (sizeof(Elemento_T));

	if (nuevo_elem == NULL) {
		printf("-> Problema al reservar memoria \n");
		return FALSE;
	}

	nuevo_elem->est = entrada;
	nuevo_elem->sig = NULL;

	lista->tam++;
	lista->primero = nuevo_elem;
	lista->ultimo = nuevo_elem;

	printf("-> Elemento INICIAL insertado correctamente \n");
	return TRUE;
}


/**
 * Inserta un elemento al final de la lista
 */
Boolean insertarElementoFinal(Lista_T *lista, Estructura_T entrada) {
	Elemento_T *nuevo_elemento;

	nuevo_elemento = (Elemento_T *) malloc (sizeof(Elemento_T));

	if (nuevo_elemento == NULL) {
		printf("-> Problema al reservar memoria \n");
		return FALSE;
	}

	nuevo_elemento->est = entrada;
	nuevo_elemento->sig = NULL;

	lista->tam++;
	lista->ultimo->sig = nuevo_elemento;
	lista->ultimo = nuevo_elemento;

	printf("-> Elemento FINAL insertado correctamente \n");
	return TRUE;
}


/**
 * Inserta un elemento al principio de la lista
 */
Boolean insertarElementoInicio(Lista_T *lista, Estructura_T entrada) {
	Elemento_T *nuevo_elemento;

	nuevo_elemento = (Elemento_T *) malloc (sizeof(Elemento_T));

	if (nuevo_elemento == NULL) {
		printf("-> Problema al reservar memoria \n");
		return FALSE;
	}

	nuevo_elemento->est = entrada;
	nuevo_elemento->sig = lista->primero;

	lista->tam++;
	lista->primero = nuevo_elemento;

	printf("-> Elemento insertado correctamente al INICIO \n");
	return TRUE;
}


/**
 * Inserta un elemento en la lista, indistintamente del orden
 */
Boolean insertarElemento(Lista_T *lista, Estructura_T entrada) {
	int ret;
	if (lista->primero == NULL) {
		ret = insertarPrimerElemento(lista, entrada);
	} else {
		ret = insertarElementoFinal(lista, entrada);
	}
	return ret;
}


/**
 * Obtiene la direccion de memoria (puntero) de la estructura que se
 * encuentra almacenada en la lista, y en el indice indicado. Tiene
 * en cuenta los posibles errores de desbordamiento.
 */
Estructura_T *obtenerElementoIndex(Lista_T *lista, int index) {

	int i;
	Elemento_T *temp;

	/* Comprobamos los limites */
	if (lista->tam < index) {
		printf("-> Error critico: El indice supera los limites! \n");
		exit(1);
	}

	/* Recorremos la lista */
	i = 0;
	temp = lista->primero;
	while (temp != NULL) {

		if (i == index) {
			/* Devolvemos la direccion de memoria
			 * referente a la estructura est
			 */
			return &(temp->est);
		}

		temp = temp->sig;
		i++;
	}
	return NULL;
}


/**
 * Muestra todos los elementos de la lista
 */
void mostrarListaEnlazada(Lista_T *lista) {
	Elemento_T *elem;

	elem = lista->primero;
	while (elem != NULL) {
		mostrarElemento(elem);
		elem = elem->sig;
	}
}


void mostrarElemento(Elemento_T *entrada) {
	printf("Valor = %d \n", entrada->est.valor);
}
